package com.diligent.cloud.sfc.service.impl;

import com.canny.commons.model.Codes;
import com.canny.commons.model.ListResult;
import com.canny.commons.model.ObjectResult;
import com.canny.commons.model.Result;
import com.canny.commons.page.IPage;
import com.canny.commons.page.Pagination;
import com.codingapi.txlcn.tc.annotation.LcnTransaction;
import com.diligent.cloud.logistics.container.enums.BoxStatus;
import com.diligent.cloud.logistics.container.model.LcmBoxFillDetail;
import com.diligent.cloud.logistics.container.model.LcmBoxFillMaster;
import com.diligent.cloud.logistics.container.service.LcmBoxFillDetailFeignService;
import com.diligent.cloud.logistics.container.service.LcmBoxFillMasterFeignService;
import com.diligent.cloud.mrp.feign.service.MrpFeignService;
import com.diligent.cloud.primary.data.feign.service.mdm.MdmBaseFeignService;
import com.diligent.cloud.primary.data.model.Period;
import com.diligent.cloud.primary.data.model.rt.RtWorkCenter;
import com.diligent.cloud.sfc.config.OauthConfig;
import com.diligent.cloud.sfc.model.OperationCompleteParams;
import com.diligent.cloud.sfc.model.OrderCompleteParams;
import com.diligent.cloud.sfc.model.OrderType;
import com.diligent.cloud.sfc.service.ISfcService;
import com.diligent.cloud.sfc.service.WipService;
import com.diligent.cloud.sfc.service.WoOperationService;
import com.diligent.cloud.sfc.util.ConverterUtil;
import com.diligent.cloud.web.model.PageAndCondition;
import com.diligent.cloud.wip.core.vo.GuideDetail;
import com.diligent.cloud.wip.core.vo.GuideMaster;
import com.diligent.cloud.wip.panel.feign.service.WipStorageBinFeignService;
import com.diligent.cloud.wip.panel.modle.WipStorageBin;
import com.diligent.cloud.workorder.enums.WoLotsStatus;
import com.diligent.cloud.workorder.enums.WoOrderStatus;
import com.diligent.cloud.workorder.model.*;
import com.diligent.cloud.workorder.service.*;
import com.diligent.cloud.workordermd.model.MfgUserEnvironment;
import com.diligent.foundation.data.model.v2.Condition;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import io.sentry.connection.RandomEventSampler;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.security.Principal;
import java.util.*;


/**
 * WoOperationService class
 *
 * @author xf107278
 * @date 3/30/2020
 */
@Service
public class WoOperationServiceImpl implements WoOperationService {

    private WoOrderCompleteDetailFeignService orderCompleteDetailFeignService;

    private WoOperationCompleteDetailFeignService woOperationCompleteDetailFeignService;

    private WoOrderFeignService orderFeignService;

    private WoOperationFeignService operationFeignService;

    private ISfcService sfcService;

    private WipService wipService;

    private LcmBoxFillMasterFeignService lcmBoxFillMasterFeignService;

    private LcmBoxFillDetailFeignService lcmBoxFillDetailFeignService;

    private WoOrderCompleteFeignService orderCompleteFeignService;

    private final WipStorageBinFeignService wipStorageBinFeignService;

    private final WoLotsFeignService woLotsFeignService;
    private final OauthConfig.RequestParams requestParams;
    private final MdmBaseFeignService mdmBaseFeignService;
    private final MrpFeignService mrpFeignService;


    public WoOperationServiceImpl(WoOrderCompleteDetailFeignService orderCompleteDetailFeignService,
                                  WoOperationCompleteDetailFeignService woOperationCompleteDetailFeignService,
                                  WoOrderFeignService orderFeignService,
                                  WoOperationFeignService operationFeignService, ISfcService sfcService,
                                  WipService wipService, LcmBoxFillMasterFeignService lcmBoxFillMasterFeignService,
                                  LcmBoxFillDetailFeignService lcmBoxFillDetailFeignService,
                                  WoOrderCompleteFeignService orderCompleteFeignService,
                                  WipStorageBinFeignService wipStorageBinFeignService,
                                  WoLotsFeignService woLotsFeignService, OauthConfig.RequestParams requestParams,
                                  MdmBaseFeignService mdmBaseFeignService, MrpFeignService mrpFeignService) {
        this.orderCompleteDetailFeignService = orderCompleteDetailFeignService;
        this.woOperationCompleteDetailFeignService = woOperationCompleteDetailFeignService;
        this.orderFeignService = orderFeignService;
        this.operationFeignService = operationFeignService;
        this.sfcService = sfcService;
        this.wipService = wipService;
        this.lcmBoxFillMasterFeignService = lcmBoxFillMasterFeignService;
        this.lcmBoxFillDetailFeignService = lcmBoxFillDetailFeignService;
        this.orderCompleteFeignService = orderCompleteFeignService;
        this.wipStorageBinFeignService = wipStorageBinFeignService;
        this.woLotsFeignService = woLotsFeignService;
        this.requestParams = requestParams;
        this.mdmBaseFeignService = mdmBaseFeignService;
        this.mrpFeignService = mrpFeignService;
    }

    /**
     * @param completeParams
     * @param isHanging      true挂料、false装框
     * @param principal
     * @return
     */
    @Override
    @Transactional
    @LcnTransaction
    public ResponseEntity<Result> addOrderComplete(OrderCompleteParams completeParams, Boolean isHanging,
                                                   Principal principal) {


        ResponseEntity<com.diligent.cloud.primary.data.model.Result> orderResult =
                orderFeignService.selectById(completeParams.getOrderId());
        Preconditions.checkNotNull(orderResult.getBody(),"查询不到此[%s]工单",completeParams.getOrderId());
        WoOrder order = (WoOrder) orderResult.getBody().getData();

        PageAndCondition pageAndCondition = new PageAndCondition();
        pageAndCondition.setPagination(new Pagination(1L, 1L));
        pageAndCondition.setConditions(Collections.singletonList(new Condition("woOrderId", "eq", order.getId(),
                null)));
        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOrderCompleteDetail>>> page =
                orderCompleteDetailFeignService.page(pageAndCondition);
        if (page.getBody()!=null && page.getBody().getData().getRecords().size() != 0) {
            ObjectResult result = new ObjectResult("");
            result.modifyCode(Codes.success.getCode(), "工单已完工");
            return ResponseEntity.ok(result);
        }

        RtWorkCenter workCenterByCwocCode = sfcService.getWorkCenterByCwocCode(order.getWorkCenterCode());

        String boxCode = null;

        //挤压完工
        if (order.getOrderType().equals(OrderType.挤压工单) & WoOrderStatus.finish.getStatus().equals(order.getOrderStatus())) {
            if (completeParams.getBoxIds() == null || completeParams.getBoxIds().size() <= 0) {
                ObjectResult objectResult = new ObjectResult<>();
                objectResult.modifyCode(Codes.fail.getCode(), "请先进行报数!");
                return ResponseEntity.ok(objectResult);
            }

            LcmBoxFillMaster lcmBoxFillMaster;
            pageAndCondition.setPagination(new Pagination(1L, 100000L));
            ArrayList<Condition> conditions;
            //查询库位
            WipStorageBin storageBin =
                    getEmbryoStorageBinByStorageCode(workCenterByCwocCode.getStorageCode(), principal);
            for (Long boxId : completeParams.getBoxIds()) {
                //框装满
                conditions = new ArrayList<>();
                conditions.add(new Condition("boxId", "eq", boxId, null));
                pageAndCondition.setConditions(conditions);
                ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<LcmBoxFillMaster>>> lcmBoxFillMasterPage =
                        lcmBoxFillMasterFeignService.page(pageAndCondition);
                List<LcmBoxFillDetail> lcmBoxFillDetails = new ArrayList<>();
                if (lcmBoxFillMasterPage.getBody()==null){continue;}
                for (LcmBoxFillMaster boxFillMaster : lcmBoxFillMasterPage.getBody().getData().getRecords()) {
                    boxCode = boxFillMaster.getBoxCode();
                    //挂料
                    if (isHanging) {
                        lcmBoxFillMaster = new LcmBoxFillMaster();
                        lcmBoxFillMaster.setId(boxFillMaster.getId());
                        lcmBoxFillMaster.setDocStatus(BoxStatus.INSTALLED.getStatus());
                        lcmBoxFillMasterFeignService.update(lcmBoxFillMaster);

                    }
                    pageAndCondition.setConditions(Collections.singletonList(new Condition("masterId", "eq",
                            boxFillMaster.getId(),
                            null)));
                    ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<LcmBoxFillDetail>>> lcmBoxFillDetailPage =
                            lcmBoxFillDetailFeignService.page(pageAndCondition);
//                    //挂料
//                    if (isHanging) {
//                        //挂料工位坯料入库成功，直接到喷涂上粉
//                        RefSprayWoOrder refSprayWoOrder = new RefSprayWoOrder();
//                        RefSprayWoOrder.RowBean rowBean = new RefSprayWoOrder.RowBean();
//                        rowBean.setDigit(String.valueOf(completeParams.getDigit()));
//                        rowBean.setMatcode(order.getMatCode());
//                        rowBean.setBatchcode(order.getBatchCode());
//                        rowBean.setMachcode("B2102");
//                        rowBean.setIspk("已上架");
//                        rowBean.setArea("100");
//                        rowBean.setWght("100");
//                        rowBean.setCprjnum("1");
//                        rowBean.setSydigit("1");
//
//                        rowBean.setCv1(order.getColorGroupCode());
//                        rowBean.setCv1name(order.getColorGroupName());
//                        DateTimeFormatter df1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//                        rowBean.setEndtime(df1.format(LocalDateTime.now()));
//                        rowBean.setTxtmemo(order.getRemark());
//                        rowBean.setStatetime(df1.format(LocalDateTime.now()));
//                        List<RefSprayWoOrder.RowBean> rowBeans = new ArrayList<>();
//                        rowBeans.add(rowBean);
//                        refSprayWoOrder.setRow(rowBeans);
//                        mrpFeignService.addSprayWoOrder((JSONObject) JSONObject.toJSON(refSprayWoOrder));
//                    } else {
                    //装框入库
                    if (lcmBoxFillDetailPage.getBody()!=null && lcmBoxFillDetailPage.getBody().getData()!=null
                            && lcmBoxFillDetailPage.getBody().getData().getRecords().size() != 0) {

                        lcmBoxFillDetails.add(lcmBoxFillDetailPage.getBody().getData().getRecords().stream().findFirst().get());

                        conditions = new ArrayList<>();
                        conditions.add(new Condition("woOrder", "eq", completeParams.getWoOrder(), null));
                        conditions.add(new Condition("isCanceled", "eq", 0, null));

                        pageAndCondition.setConditions(conditions);
                        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoLots>>> woLotsPage =
                                woLotsFeignService.page(pageAndCondition);
                        if (woLotsPage.getBody()==null){continue;}
                        for (WoLots woLots : woLotsPage.getBody().getData().getRecords()) {
                            woLots.setLotState(WoLotsStatus.INLOTS.getStatus());
                            woLotsFeignService.update(woLots);
                        }
                    }
                    //查询车间信息
                    RtWorkCenter workCenter = sfcService.getWorkCenterByCwocCode(order.getWorkCenterCode());
                    //生成仓单信息
                    GuideMaster guideMaster = sfcService.generateWipStockOrderInfo(boxId, 1L,
                            storageBin, workCenter, lcmBoxFillDetails);
                    ResponseEntity<ObjectResult> objectResultResponseEntity = wipService.addMatStorage(guideMaster,
                            principal);
                    //胚料入库
                    if (objectResultResponseEntity.getBody()==null && objectResultResponseEntity.getBody().getCode()==null ) {
                        throw new RuntimeException("胚料入库失败");
                    }
                }
            }
     //   } else if (OrderType.表面处理工单.equals(order.getOrderType()) || OrderType.后加工工单.equals(order.getOrderType())) {
        } else if (OrderType.表面处理工单.equals(order.getOrderType()) ) {
            mrpFeignService.addPackageWoOrder(order);
        }

        Long periodId = sfcService.getPeriodId();
        //工单完工报数
        WoOrderCompleteMaster woOrderCompleteMaster = new WoOrderCompleteMaster();

        WoOrderCompleteDetail woOrderCompleteDetail = new WoOrderCompleteDetail();

        MfgUserEnvironment userEnvironmentByUserCode = sfcService.getUserEnvironmentByUserCode(principal.getName());

        woOrderCompleteMaster.setMachCode(completeParams.getMachCode());
        woOrderCompleteMaster.setEnterCode(principal.getName());
        woOrderCompleteMaster.setEnterName(principal.getName());
        woOrderCompleteMaster.setEnterTime(new Date());
        BeanUtils.copyProperties(completeParams, woOrderCompleteDetail);
        woOrderCompleteMaster.setCwocCode(order.getWorkCenterCode());
        woOrderCompleteMaster.setCwocName(order.getWorkCenterName());
        woOrderCompleteMaster.setCrewCode(userEnvironmentByUserCode.getCrewCode());
        woOrderCompleteMaster.setCrewName(userEnvironmentByUserCode.getCrewName());
        woOrderCompleteMaster.setStorageCode(order.getStroageCode());
        woOrderCompleteMaster.setStorageName(order.getStroageName());
        woOrderCompleteMaster.setMachName(order.getMachineName());
        woOrderCompleteMaster.setWorkCenterCode(order.getWorkCenterCode());
        woOrderCompleteMaster.setWorkCenterName(order.getWorkCenterName());
        woOrderCompleteMaster.setCompanyId(requestParams.getCompanyId());
        woOrderCompleteMaster.setSystemId(requestParams.getSystemId());
        woOrderCompleteMaster.setPeriodId(periodId);
        woOrderCompleteMaster.setFormId(1L);


        woOrderCompleteDetail.setEnterCode(principal.getName());
        woOrderCompleteDetail.setEnterName(principal.getName());
        woOrderCompleteDetail.setEnterTime(new Date());

        woOrderCompleteDetail.setWoOrderId(completeParams.getOrderId());
        woOrderCompleteDetail.setWoOrder(completeParams.getWoOrder());
        woOrderCompleteDetail.setBatchCode(order.getBatchCode());
        woOrderCompleteDetail.setRequireDigit(order.getDeliveryDigit());
        woOrderCompleteDetail.setMatCode(order.getMatCode());
        woOrderCompleteDetail.setMatName(order.getMatName());
        woOrderCompleteDetail.setCompanyId(requestParams.getCompanyId());
        woOrderCompleteDetail.setSystemId(requestParams.getSystemId());
        woOrderCompleteDetail.setPeriodId(periodId);
        woOrderCompleteDetail.setStorageCode(order.getStroageCode());
        woOrderCompleteDetail.setStorageName(order.getStroageName());
        woOrderCompleteDetail.setClientCode(order.getClientCode());
        woOrderCompleteDetail.setProjectCode(order.getProjectCode());
        woOrderCompleteDetail.setOrderDate(order.getOrderDate());
        woOrderCompleteDetail.setDeliveryDate(order.getDeliveryDate());
        woOrderCompleteDetail.setBoxCode(boxCode);

        woOrderCompleteMaster.setWoOrderCompleteDetail(Collections.singletonList(woOrderCompleteDetail));
        WoOperationCompleteDetail operationCompleteDetailByWoOrder =
                sfcService.getOperationCompleteDetailByWoOrder(order.getWoOrder());

        if (operationCompleteDetailByWoOrder != null) {
            woOrderCompleteDetail.setProdBatch(operationCompleteDetailByWoOrder.getProdBatch());
        }

        ResponseEntity<com.diligent.cloud.primary.data.model.Result> insert =
                orderCompleteFeignService.insert(woOrderCompleteMaster);
        ObjectResult result;
        if (insert.getBody()!=null && insert.getBody().getCode()==0){

            result = new ObjectResult(insert.getBody().getData());
        }else {
            result = new ObjectResult();
            result.modifyCode(Codes.fail.getCode(),"新增完工单失败");
        }
        return ResponseEntity.ok(result);
    }

    @Override
    public ResponseEntity<Result> addOperation(WoOperation woOperation, Principal principal) {
        woOperation.setEnterCode(principal.getName());
        woOperation.setEnterName(principal.getName());
        woOperation.setEnterTime(new Date());
        ResponseEntity<com.diligent.cloud.primary.data.model.Result> insert = operationFeignService.insert(woOperation);
       if (insert.getBody()!=null && insert.getBody().getCode()==0){
           return ResponseEntity.ok(new ObjectResult<>(insert.getBody().getData()));
       }else {
           ObjectResult result = new ObjectResult();
           result.modifyCode(Codes.fail.getCode(),"新增工序单失败");
           return ResponseEntity.ok(result);
       }
    }

    @Override
    public ResponseEntity<Result> addOperationComplete(OperationCompleteParams operationCompleteParams,
                                                       Principal principal) {
        PageAndCondition pageAndCondition = new PageAndCondition();
        pageAndCondition.setPagination(new Pagination(1L, 10L));
        pageAndCondition.setConditions(Collections.singletonList(new Condition("woOrder", "eq",
                operationCompleteParams.getWoOrder(), null)));

        ResponseEntity<com.diligent.cloud.primary.data.model.Result<IPage<WoOperationCompleteDetail>>> operationCompleteDetailPage =
                woOperationCompleteDetailFeignService.page(pageAndCondition);

        if (operationCompleteDetailPage.getBody()!=null && operationCompleteDetailPage.getBody().getData().getRecords().size() != 0) {
            WoOperationCompleteDetail operationCompleteDetail =
                    operationCompleteDetailPage.getBody().getData().getRecords().stream().findFirst().get();


            operationCompleteDetail.setDigit(operationCompleteParams.getDigit());
            operationCompleteDetail.setBaseDigit(operationCompleteParams.getBaseDigit());
            operationCompleteDetail.setInvDigit(operationCompleteParams.getInvDigit());

            operationCompleteDetail.setDefectDigit(operationCompleteParams.getDefectDigit());
            operationCompleteDetail.setDefectName(operationCompleteParams.getDefectName());

            operationCompleteDetail.setModifyCode(principal.getName());
            operationCompleteDetail.setModifyName(principal.getName());
            operationCompleteDetail.setModifyTime(new Date());

            ResponseEntity<com.diligent.cloud.primary.data.model.Result> update =
                    woOperationCompleteDetailFeignService.update(operationCompleteDetail);

            return ResponseEntity.ok(ConverterUtil.ConverterByResult(update.getBody()));
        } else {
            throw new NullPointerException(Strings.lenientFormat("查询不到此【%s】工序完工单",
                    operationCompleteParams.getWoOrder()));
        }
    }

    //获取胚料线边库位
    private WipStorageBin getEmbryoStorageBinByStorageCode(String storageCode, Principal principal) {
        PageAndCondition pageAndCondition = new PageAndCondition();
        List<Condition> conditions = new ArrayList<>();
        pageAndCondition.setPagination(new Pagination(1L, 1L));
        conditions.add(new Condition("binCode", "eq", "1", null));
        conditions.add(new Condition("storageCode", "eq", storageCode, null));
        pageAndCondition.setConditions(conditions);

        ListResult<WipStorageBin> wipStorageBinListResult = wipStorageBinFeignService.listByConditions(conditions);
        if (wipStorageBinListResult.getData().size() == 0) {
            WipStorageBin wipStorageBin = new WipStorageBin();
            wipStorageBin.setStorageCode(storageCode);
            wipStorageBin.setBinCode("1");
            wipStorageBin.setBinName("默认胚料库位");
            wipStorageBin.setSystemId(requestParams.getSystemId());
            wipStorageBin.setCompanyId(requestParams.getCompanyId());
            wipService.addWipStorageBin(wipStorageBin, principal);
            return wipStorageBin;
        } else {
            return wipStorageBinListResult.getData().stream().findFirst().get();
        }
    }


}
